/* 
* 
* TabVD is a Virtual Desktop Client/Server designed specifically for connecting 
*  from Tablet like devices.
*  
*  Copyright (C) 2011 Subhabrata Ghosh 
*  
*  This program is free software: you can redistribute it and/or modify it under 
*  the terms of the GNU General Public License as published by the Free Software 
*  Foundation, either version 3 of the License, or (at your option) any later 
*  version. 
*  
*  This program is distributed in the hope that it will be useful, but WITHOUT 
*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
*  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 
*  details. 
*  
*  You should have received a copy of the GNU General Public License along with 
*  this program. If not, see <http://www.gnu.org/licenses/>. 
* 
* 
*/

#ifndef CONFIGURATIONDEFS_H_
#define CONFIGURATIONDEFS_H_

#include <string>

namespace tabvd {
	/* --------------------------------------------------------------------------*/
	/**
	 * @Synopsis Struct to store the configuration definition.
	 * 
	 * The configuration definition is as follow:
	 * 	Key -> Lookup Key for the configuration element.
	 * 	Name -> Display Name for the configuration element.
	 * 	Mandatory -> Is the field a mandatory element. 
	 */
	/* ----------------------------------------------------------------------------*/
	class ConfigElement {
		protected:
			std::string* key;
			std::string* name;
			bool mandatory;
            bool visible;

		public:
			ConfigElement(){
				key = NULL;
				name = NULL;
				mandatory = false;
                visible = false;
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis  Copy Constructor.
			 *
			 * @Param el
			 */
			/* ----------------------------------------------------------------------------*/
			ConfigElement(const ConfigElement& el){
				if (el.key)
					key = new std::string(*el.key);
				if (el.name)
					name = new std::string(*el.name);
				mandatory = el.mandatory;
                visible = el.visible;
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis Default Constructor - Initializes all the fields. 
			 *
			 * @Param k - Key
			 * @Param n - Name
			 * @Param m - Mandatory
			 * @Param v - Visibility
			 */
			/* ----------------------------------------------------------------------------*/
			ConfigElement(std::string k, std::string n, bool m, bool v){
                key = NULL;
				name = NULL;
				mandatory = false;
                visible = false;

				setdata(k, n, m, v);
			}

			~ConfigElement() {
				if (key)
					delete key;
				if (name)
					delete name;
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis Set the configuration element values. 
			 *
			 * @Param k - Key
			 * @Param n - Name
			 * @Param m - Mandatory
			 * @Param v - Visibility
			 *
			 * @Returns   
			 */
			/* ----------------------------------------------------------------------------*/
			bool setdata(const std::string k, const std::string n, bool m, bool v){

				if (key != NULL){
					key->assign(k);
				} else {
					key = new std::string(k);
					if (key == NULL)
						return false;
				}
				if (name != NULL){
					name->assign(n);
				} else {
					name = new std::string(n);
					if (name == NULL)
						return false;
				}

				mandatory = m;
                visible = v;

				return true;
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis Is the element mandatory. 
			 *
			 * @Returns   
			 */
			/* ----------------------------------------------------------------------------*/
			bool ismandatory() {
				return mandatory;
			}

            /* --------------------------------------------------------------------------*/
            /**
            * @Synopsis  Is the element visiable to the users.
            *
            * Basically indicates whether the element is user configurable or an
            * internal setting which shouldn't be exposed.
            *
            * @Returns   
            */
            /* ----------------------------------------------------------------------------*/
            bool isvisible() {
                return visible;
            }

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis Get the lookup key. 
			 *
			 * @Returns   
			 */
			/* ----------------------------------------------------------------------------*/
			const std::string* getkey(){
				return key;
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis Get the element name. 
			 *
			 * @Returns   
			 */
			/* ----------------------------------------------------------------------------*/
			const std::string* getname() {
				return name;
			}
	};

	/* --------------------------------------------------------------------------*/
	/**
	 * @Synopsis Struct to store the configuration value. 
	 */
	/* ----------------------------------------------------------------------------*/
	class ConfigValue {
		protected:
			ConfigElement* element;
			std::string* value;

		public:
			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis Kind of Copy Constructor. 
			 *
			 * @Param el
			 */
			/* ----------------------------------------------------------------------------*/
			ConfigValue(ConfigElement* el){
				element = el;
				value = NULL;
			}

			ConfigValue(const ConfigValue& cv) {
				if (cv.element)
					element = new ConfigElement(*cv.element);
				if (cv.value)
					value = new std::string(*cv.value);
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis  
			 *
			 * @Param el
			 * @Param v
			 */
			/* ----------------------------------------------------------------------------*/
			ConfigValue(ConfigElement& el, std::string v){
                element = NULL;
                value = NULL;

				setdata(el, v);
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis  
			 *
			 * @Param k
			 * @Param n
			 * @Param m
			 * @Param vi
			 * @Param v
			 */
			/* ----------------------------------------------------------------------------*/
			ConfigValue(std::string k, std::string n, bool m, bool vi, std::string v){
				element = new ConfigElement(k, n, m, vi);
				if (!element)
					return;
				setvalue(v);
			}

			~ConfigValue() {
				if (element)
					delete element;
				if (value)
					delete value;
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis  
			 *
			 * @Param v
			 *
			 * @Returns   
			 */
			/* ----------------------------------------------------------------------------*/
			bool setvalue(std::string v){
				if (value)
					value->assign(v);
				else {
					value = new std::string(v);
					if (!value)
						return false;
				}
				return true;
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis  
			 *
			 * @Param el
			 * @Param v
			 *
			 * @Returns   
			 */
			/* ----------------------------------------------------------------------------*/
			bool setdata(ConfigElement& el, std::string v){
				element = new ConfigElement(el);
				return setvalue(v);
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis  
			 *
			 * @Returns   
			 */
			/* ----------------------------------------------------------------------------*/
			const ConfigElement* getkey(){
				return element;
			}

			/* --------------------------------------------------------------------------*/
			/**
			 * @Synopsis  
			 *
			 * @Returns   
			 */
			/* ----------------------------------------------------------------------------*/
			const std::string& getvalue() {
				return *value;
			}
	};    
};
#endif //CONFIGURATIONDEFS_H_
